import 'package:flutter/material.dart';
import 'package:flutter_gallery/demos/material/material_demo_types.dart';
import 'package:flutter_gen/gen_l10n/gallery_localizations.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';

class PickerDemo extends StatefulWidget {
  const PickerDemo({Key? key, required this.type}) : super(key: key);

  final PickerDemoType type;

  @override
  _PickerDemoState createState() => _PickerDemoState();
}

class _PickerDemoState extends State<PickerDemo> with RestorationMixin {
  final RestorableDateTime _fromDate = RestorableDateTime(DateTime.now());
  final RestorableTimeOfDay _fromTime =
      RestorableTimeOfDay(TimeOfDay.fromDateTime(DateTime.now()));
  final RestorableDateTime _startDate = RestorableDateTime(DateTime.now());
  final RestorableDateTime _endDate = RestorableDateTime(DateTime.now());

  late RestorableRouteFuture<DateTime> _restorableDatePickerRouteFuture;
  late RestorableRouteFuture<DateTimeRange>
      _restorableDateRangePickerRouteFuture;
  late RestorableRouteFuture<TimeOfDay> _restorableTimePickerRouteFuture;

  void _selectDate(DateTime selectedDate) {
    if (selectedDate != _fromDate.value) {
      setState(() {
        _fromDate.value = selectedDate;
      });
    }
  }

  void _selectDateRange(DateTimeRange newSelectedDate) {
    setState(() {
      _startDate.value = newSelectedDate.start;
      _endDate.value = newSelectedDate.end;
    });
  }

  void _selectTime(TimeOfDay selectedTime) {
    if (selectedTime != _fromTime.value) {
      setState(() {
        _fromTime.value = selectedTime;
      });
    }
  }

  static Route<DateTime> _datePickerRoute(
          BuildContext context, Object? arguments) =>
      DialogRoute<DateTime>(
          context: context,
          builder: (context) => DatePickerDialog(
                restorationId: 'date_picker_dialog',
                initialDate:
                    DateTime.fromMillisecondsSinceEpoch(arguments as int),
                firstDate: DateTime(2015, 1),
                lastDate: DateTime(2100),
              ));

  static Route<TimeOfDay> _timePickerRoute(
      BuildContext context, Object? arguments) {
    final args = arguments as List<Object>;
    final initialTime = TimeOfDay(hour: args[0] as int, minute: args[1] as int);

    return DialogRoute<TimeOfDay>(
        context: context,
        builder: (context) => TimePickerDialog(
              restorationId: 'time_picker_dialog',
              initialTime: initialTime,
            ));
  }

  static Route<DateTimeRange> _dateRangePickerRoute(
          BuildContext context, Object? arguments) =>
      DialogRoute<DateTimeRange>(
          context: context,
          builder: (context) => DateRangePickerDialog(
                restorationId: 'date_rage_picker_dialog',
                // helpText: 'helpText',
                // cancelText: 'cancelText',
                // initialDateRange: DateTimeRange(
                //     start: DateTime(DateTime.now().day - 5),
                //     end: DateTime(DateTime.now().day + 5)),
                firstDate: DateTime(DateTime.now().year - 5),
                lastDate: DateTime(DateTime.now().year + 5),
              ));

  @override
  void initState() {
    super.initState();
    _restorableDatePickerRouteFuture = RestorableRouteFuture(
        onComplete: _selectDate,
        onPresent: (navigator, arguments) => navigator.restorablePush(
            _datePickerRoute,
            arguments: _fromDate.value.millisecondsSinceEpoch));

    _restorableDateRangePickerRouteFuture = RestorableRouteFuture(
        onComplete: _selectDateRange,
        onPresent: (navigator, arguments) =>
            navigator.restorablePush(_dateRangePickerRoute));

    _restorableTimePickerRouteFuture = RestorableRouteFuture(
        onComplete: _selectTime,
        onPresent: (navigator, arguments) => navigator.restorablePush(
            _timePickerRoute,
            arguments: [_fromTime.value.hour, _fromTime.value.minute]));
  }

  @override
  String? get restorationId => 'picker_demo';

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    registerForRestoration(_fromDate, 'from_date');
    registerForRestoration(_fromTime, 'fromTime');
    registerForRestoration(_startDate, 'startDate');
    registerForRestoration(_endDate, 'endDate');
    registerForRestoration(
        _restorableDatePickerRouteFuture, 'date_picker_route');
    registerForRestoration(
        _restorableDateRangePickerRouteFuture, 'date_range_picker_route');
    registerForRestoration(
        _restorableTimePickerRouteFuture, 'time_picker_route');
  }

  String get _title {
    switch (widget.type) {
      case PickerDemoType.date:
        return GalleryLocalizations.of(context)!.demoDatePickerTitle;
      case PickerDemoType.time:
        return GalleryLocalizations.of(context)!.demoTimePickerTitle;
      case PickerDemoType.range:
        return GalleryLocalizations.of(context)!.demoDateRangePickerTitle;
    }
  }

  String get _labelText {
    switch (widget.type) {
      case PickerDemoType.date:
        return DateFormat.yMMMd().format(_fromDate.value);
      case PickerDemoType.time:
        return _fromTime.value.format(context);
      case PickerDemoType.range:
        return DateFormat.yMMMd().format(_startDate.value) +
            ' - ' +
            DateFormat.yMMMd().format(_endDate.value);
    }
  }

  @override
  void dispose() {
    _fromDate.dispose();
    _fromTime.dispose();
    _startDate.dispose();
    _endDate.dispose();
    _restorableDatePickerRouteFuture.dispose();
    _restorableDateRangePickerRouteFuture.dispose();
    _restorableTimePickerRouteFuture.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Navigator(
      onGenerateRoute: (settings) => MaterialPageRoute(
        builder: (context) => Scaffold(
          appBar: AppBar(
            automaticallyImplyLeading: false,
            title: Text(_title),
          ),
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(_labelText),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () {
                    switch (widget.type) {
                      case PickerDemoType.date:
                        _restorableDatePickerRouteFuture.present();
                        break;
                      case PickerDemoType.time:
                        _restorableTimePickerRouteFuture.present();
                        break;
                      case PickerDemoType.range:
                        _restorableDateRangePickerRouteFuture.present();
                        break;
                    }
                  },
                  child: Text(
                    GalleryLocalizations.of(context)!.demoPickersShowPicker,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
